/*
*
*
*     文档创建：jjl, jjl@hzncc.com
*/


module rmii_crc32(
    input               phy_clk         ,       //RMII时钟
    input               sys_reset_n     ,       //系统复位
    input               crc_enable      ,       //为1:每个clk计算一次CRC，为0 crc复位初始值
    input   [1:0]       data_in         ,       //输入需要计算的数据
    output  [31:0]      crc_out                 //CRC计算结果             
        );

//CRC32多项式 0x04c11db7,这部分的组合逻辑封装成一个函数
function [31:0] crc32;
	input	[31:0] crc;
	input	[1:0]	data;
	begin
		crc32[0] = crc[30] ^ data[1];
		crc32[1] = crc[30] ^ crc[31] ^ data[0] ^ data[1];
		crc32[2] = crc[0] ^ crc[30] ^ crc[31] ^ data[0] ^ data[1];
		crc32[3] = crc[1] ^ crc[31] ^ data[0];
		crc32[4] = crc[2] ^ crc[30] ^ data[1];
		crc32[5] = crc[3] ^ crc[30] ^ crc[31] ^ data[0] ^ data[1];
		crc32[6] = crc[4] ^ crc[31] ^ data[0];
		crc32[7] = crc[5] ^ crc[30] ^ data[1];
		crc32[8] = crc[6] ^ crc[30] ^ crc[31] ^ data[0] ^ data[1];
		crc32[9] = crc[7] ^ crc[31] ^ data[0];
		crc32[10] = crc[8] ^ crc[30] ^ data[1];
		crc32[11] = crc[9] ^ crc[30] ^ crc[31] ^ data[0] ^ data[1];
		crc32[12] = crc[10] ^ crc[30] ^ crc[31] ^ data[0] ^ data[1];
        crc32[13] = crc[11] ^ crc[31] ^ data[0];
        crc32[14] = crc[12];
        crc32[15] = crc[13];
        crc32[16] = crc[14] ^ crc[30] ^ data[1];
        crc32[17] = crc[15] ^ crc[31] ^ data[0];
        crc32[18] = crc[16];
        crc32[19] = crc[17];
        crc32[20] = crc[18];
        crc32[21] = crc[19];
        crc32[22] = crc[20] ^ crc[30] ^ data[1];
        crc32[23] = crc[21] ^ crc[30] ^ crc[31] ^ data[0] ^ data[1];
        crc32[24] = crc[22] ^ crc[31] ^ data[0];
        crc32[25] = crc[23];
        crc32[26] = crc[24] ^ crc[30] ^ data[1];
        crc32[27] = crc[25] ^ crc[31] ^ data[0];
        crc32[28] = crc[26];
        crc32[29] = crc[27];
        crc32[30] = crc[28];
        crc32[31] = crc[29];
	end
endfunction

reg     [31:0]      crc_r   ;
always @(posedge phy_clk or negedge sys_reset_n)
if(~sys_reset_n) begin
    crc_r <= 32'h0000_0000;
end else if(crc_enable) begin //如果CRC使能
    crc_r <= crc32(crc_r, data_in);
end else begin  //CRC置初始值
    crc_r <= 32'hffff_ffff;
end

assign crc_out = crc_r;

endmodule
